/**
 * 媒体上传
 * 
 * Example:
 * import Upload from '@/utils/upload'
 * const {uploadImage, uploadVideo, uploadMedia} = new Upload({ count:6 })
 */

import { identifyYellow } from '@/apis/public/index.js';
import getFileExtension from '@/utils/get-file-extension.js'
import {baseHost} from '@/setting.js'
const ENV_URL = process.env.NODE_ENV === 'development' ? `${baseHost.car}/api/common/upload` : `${baseHost.car}/api/common/upload`

export default class Upload {
		constructor (config = {}) {
		this.url = config.url || ENV_URL  // 上传地址
		this.name = config.name || 'file' // 上传字段名称
		this.count = config.count || 1    // 限制选择数量 1 ~ 9
		this.idealSize = config.idealSize || 300  // 理想压缩尺寸 300KB
		this.checkType = config.checkType || null // 鉴黄模块 md 门店、zj 组局
		
		this.checkImage = this.checkImage.bind(this)
		this.compressImage = this.compressImage.bind(this)
		this.uploadImage = this.uploadImage.bind(this)
		this.uploadVideo = this.uploadVideo.bind(this)
		this.uploadMedia = this.uploadMedia.bind(this)
  }
  
  async upload(url,filePath){
		const [,res] = await uni.uploadFile({ url, filePath, name:this.name })
		if (res.statusCode === 200) {
			 const {code,data,msg} = JSON.parse(res.data)
			 if(code === 1){
				 return data
			 }else{
				 throw new Error(msg)
			 }
		}else{
			switch (res.statusCode) {
				case 413:
				throw new Error('上传失败，文件过大！')
				case 408:
				throw new Error('上传失败，网络超时！')
				default:
				throw new Error('上传失败，未知错误！')
			}
		}
  }

/**
 * 图片鉴黄
 */
  async checkImage(imagePath){
	  const imageCode = uni.getFileSystemManager().readFileSync(imagePath,'base64')
	  const {code,data,msg} = await identifyYellow({type:this.checkType,base64:imageCode})
	  if(code === 1){
		  if(data.result_code === 1){
			  return data.result
		  }else{
			  throw new Error('图片违规，请重新选择！')
		  }
	  }else{
		  throw new Error(msg)
	  }
  }

/**
 * 图片压缩
 */
 async compressImage(imagePath){
	 const [,before] = await uni.getFileInfo({filePath:imagePath})
	 const quality = ~~(1024 * this.idealSize / before.size * 100)
	 
	 imagePath = (await uni.compressImage({src:imagePath, quality:quality < 100? quality:100}))[1].tempFilePath
	 const [,after] = await uni.getFileInfo({filePath:imagePath})
	 
	 console.log(`Compress: before ${before.size} | after ${after.size} | ratio ${(before.size/after.size).toFixed(2)} | quality ${quality}`)
	 
	 //BUG: https://developers.weixin.qq.com/community/develop/doc/000a4a770c82e08f7d1a55cc952000
	 if(/png|jpe?g/.test(getFileExtension(imagePath).toLocaleLowerCase())) return imagePath
	 const newImagePath = `${wx.env.USER_DATA_PATH}/${+ new Date}.jpg`
	 uni.getFileSystemManager().renameSync(imagePath,newImagePath) // 重命名图片
	 return newImagePath
 }
 
  /**
   * 图片上传
   */
  async uploadImage (options = {}) {
		const url = options.url || this.url
		const count = options.count || this.count
		const [error,file] = await uni.chooseImage({count:count,sizeType:['compressed']})
		if(error) throw new Error('未选择图片文件!')
		try{
			const {tempFilePaths} = file
			const minImagePaths = await Promise.all(tempFilePaths.map(filePath=>this.compressImage(filePath)))
			this.checkType && await Promise.all(minImagePaths.map(filePath=>this.checkImage(filePath)))
			uni.showLoading({title: '上传中...'})
			const data = await Promise.all(minImagePaths.map(filePath => this.upload(url,filePath)))
			uni.showToast({title: '上传完成！',icon: 'success'})
			return {data,type:'image'}
		}catch(e){
			uni.hideLoading()
			uni.showModal({ title:'出错啦！',content:e.message,showCancel:false})
			throw e
		}
  }

  /**
   * 视频上传
   */
  async uploadVideo () {
	const [error,file] = await uni.chooseVideo()
	if(error) throw new Error('未选择视频文件!')
	try{
		const {tempFilePath} = file
		uni.showLoading({title: '上传中...'})
		const [videoPath] = await this.upload(tempFilePath)
		uni.showToast({title: '上传完成！',icon: 'success'})
		return {data:{videoPath,posterPath:`${videoPath}?vframe/jpg/offset/1`},type:'video'}
	}catch(e){
		uni.hideLoading()
		uni.showModal({ title:'出错啦！',content:e.message,showCancel:false})
		throw e
	}
  }

  /**
   * 图片/视频上传
   */
  async uploadMedia(count){
	const [error,file] = await uni.chooseMedia({count:count||this.count,sizeType:['compressed']})
	if(error) throw new Error('未选择媒体文件!')
	const {tempFiles,type} = file
	if(type === 'video'){
		 const [{tempFilePath}] = tempFiles
		 try{
			uni.showLoading({title: '上传中...'})
			const [videoPath] = await this.upload(tempFilePath)
			uni.showToast({title: '上传完成！',icon: 'success'})
			return {data:{videoPath,posterPath:`${videoPath}?vframe/jpg/offset/1`},type}
		 }catch(e){
			uni.hideLoading()
			uni.showModal({ title:'出错啦！',content:e.message,showCancel:false})
			throw e
		 }
	}else if(type === 'image'){
		try{
			uni.showLoading({title: '上传中...'})
			const data = await Promise.all(tempFiles.map(item => this.upload(item.tempFilePath)))
			uni.showToast({title: '上传完成！',icon: 'success'})
			return {data,type}
		}catch(e){
			uni.hideLoading()
			uni.showModal({ title:'出错啦！',content:e.message,showCancel:false})
			throw e
		}
	}
  }
}
